/******************************************************************************* * Copyright (c) 2011 Stephan Schwiebert. All rights reserved. This program and * the accompanying materials are made available under the terms of the Eclipse * Public License v1.0 which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * <p/> * Contributors: Stephan Schwiebert - initial API and implementation *******************************************************************************/ package org.eclipse.zest.cloudio; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.List; import java.util.Map; import org.eclipse.core.runtime.Assert; import org.eclipse.jface.viewers.ColumnLabelProvider; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeContentProvider; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.FontData; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.ColorDialog; import org.eclipse.swt.widgets.Combo; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.FontDialog; import org.eclipse.swt.widgets.Group; import org.eclipse.swt.widgets.Label; /** * Provides options to modify the rendering of a {@link TagCloudViewer} using an * {@link IEditableCloudLabelProvider}. * * @author sschwieb * */ public class CloudOptionsComposite extends Composite { protected TagCloudViewer viewer; protected List<RGB> colors = new ArrayList<RGB>(); protected List<FontData> fonts = new ArrayList<FontData>(); protected List<List<RGB>> colorSchemes = new ArrayList<List<RGB>>(); protected int currentScheme; private static class ListContentProvider implements ITreeContentProvider { @Override public void dispose() {} @Override public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {} @Override public Object[] getElements(Object inputElement) { return ((List<?>)inputElement).toArray(); } @Override public Object[] getChildren(Object parentElement) { return null; } @Override public Object getParent(Object element) { return null; } @Override public boolean hasChildren(Object element) { return false; } } public CloudOptionsComposite(Composite parent, int style, TagCloudViewer viewer) { super(parent, style); Assert.isLegal(viewer.getLabelProvider() instanceof IEditableCloudLabelProvider, "Cloud label provider must be of type " + IEditableCloudLabelProvider.class); this.viewer = viewer; setLayout(new GridLayout()); addGroups(); } protected void addGroups() { addLayoutButtons(this); addColorButtons(this); addFontButtons(this); } protected void addScheme(RGB...rgbs) { List<RGB> colors = new ArrayList<RGB>(); for (RGB rgb : rgbs) { colors.add(rgb); } colorSchemes.add(colors); } protected void updateColors() { IEditableCloudLabelProvider lp = (IEditableCloudLabelProvider) viewer.getLabelProvider(); lp.setColors(colors); List<Word> words = viewer.getCloud().getWords(); for (Word word : words) { word.setColor(lp.getColor(word.data)); } viewer.getCloud().redrawTextLayerImage(); } protected void updateFonts() { IEditableCloudLabelProvider lp = (IEditableCloudLabelProvider) viewer.getLabelProvider(); lp.setFonts(fonts); } protected void initColors() { addScheme(new RGB(222, 177, 17), new RGB(97, 28, 24), new RGB(102,109,17), new RGB(189, 112, 20), new RGB(111, 92, 16), new RGB(111, 32, 27)); addScheme(new RGB(1,175,255), new RGB(57,99,213), new RGB(21,49,213), new RGB(30,125,42)); addScheme(new RGB(255,92,93), new RGB(255,0,0), new RGB(255,41,43), new RGB(182,31,32), new RGB(153,0,0)); addScheme(new RGB(255,157,0), new RGB(255,206,0), new RGB(40,0,159), new RGB(0,41,156)); addScheme(new RGB(255,46,0), new RGB(255,255,14), new RGB(183, 183, 183), new RGB(122, 122, 122), new RGB(81, 81, 81), new RGB(61, 61, 61), new RGB(165, 165, 165)); addScheme(new RGB(255,0,206), new RGB(255,220,0), new RGB(0, 255, 42)); addScheme(new RGB(89, 79, 69), new RGB(168, 165, 126), new RGB(68, 49, 14), new RGB(86, 68, 34), new RGB(148, 141, 129), new RGB(92, 90, 41)); addScheme(new RGB(66,71,37), new RGB(85,122,18), new RGB(117,131,49), new RGB(49,45,17)); addScheme(new RGB(254,213,44), new RGB(255,177,10), new RGB(233,121,0), new RGB(229,109,3), new RGB(202,80,8), new RGB(129,52,7), new RGB(89,47,14)); addScheme(new RGB(139,124,115), new RGB(91,95,129), new RGB(50,23,18), new RGB(255,251,237)); nextColors(); } protected void nextColors() { currentScheme = (currentScheme+1)%colorSchemes.size(); colors = colorSchemes.get(currentScheme); } protected Group addFontButtons(final Composite parent) { Group buttons = new Group(parent, SWT.SHADOW_IN); buttons.setLayout(new GridLayout(2, false)); buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Label l = new Label(buttons, SWT.NONE); l.setText("Fonts"); GridData gd = new GridData(); gd.horizontalSpan=2; l.setLayoutData(gd); final TreeViewer tv = new TreeViewer(buttons); Composite comp = new Composite(buttons, SWT.NONE); comp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true)); comp.setLayout(new RowLayout(SWT.VERTICAL)); tv.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); ListContentProvider cp = new ListContentProvider(); tv.setContentProvider(cp); tv.setLabelProvider(new ColumnLabelProvider() { @Override public String getText(Object element) { FontData fd = (FontData) element; return fd.getName(); } }); fonts.add(getFont().getFontData()[0]); tv.setInput(fonts); Button add = new Button(comp, SWT.FLAT); add.setImage(Activator.getDefault().getImageRegistry().get(Activator.ADD)); add.setToolTipText("Add font..."); add.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { FontDialog fd = new FontDialog(parent.getShell()); FontData fontData = fd.open(); if(fontData != null) { fonts.add(fontData); tv.setInput(fonts); updateFonts(); } } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); Button remove = new Button(comp, SWT.FLAT); remove.setToolTipText("Remove selected fonts"); remove.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { IStructuredSelection selection = (IStructuredSelection) tv.getSelection(); fonts.removeAll(selection.toList()); tv.setInput(fonts); updateFonts(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); remove.setImage(Activator.getDefault().getImageRegistry().get(Activator.REMOVE)); return buttons; } protected Image createImageFromColor(RGB rgb, int size) { Image image; Color color = new Color(Display.getDefault(), rgb); image = new Image(Display.getDefault(), size, size); GC gc = new GC(image); gc.setBackground(color); gc.fillRoundRectangle(0, 0, size, size, 3, 3); color.dispose(); gc.dispose(); return image; } protected Group addColorButtons(final Composite parent) { Group buttons = new Group(parent, SWT.SHADOW_IN); buttons.setLayout(new GridLayout(2, false)); buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Label l = new Label(buttons, SWT.NONE); l.setText("Colors"); GridData gd = new GridData(); gd.horizontalSpan=2; l.setLayoutData(gd); final TreeViewer tv = new TreeViewer(buttons); Composite comp = new Composite(buttons, SWT.NONE); comp.setLayout(new RowLayout(SWT.VERTICAL)); comp.setLayoutData(new GridData(SWT.FILL, SWT.TOP, false, true)); tv.getTree().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); ListContentProvider cp = new ListContentProvider(); tv.setContentProvider(cp); tv.setLabelProvider(new ColumnLabelProvider() { private Map<Object, Image> images = new HashMap<Object, Image>(); @Override public Image getImage(Object element) { Image image = images.get(element); if(image == null) { RGB rgb = (RGB) element; image = createImageFromColor(rgb, 24); images.put(element, image); } return image; } @Override public void dispose() { Collection<Image> images = this.images.values(); for (Image image : images) { image.dispose(); } this.images.clear(); } }); initColors(); tv.setInput(colors); Button add = new Button(comp, SWT.FLAT); add.setImage(Activator.getDefault().getImageRegistry().get(Activator.ADD)); add.setToolTipText("Add color..."); add.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { ColorDialog cd = new ColorDialog(parent.getShell()); RGB color = cd.open(); if(color != null) { colors.add(color); tv.setInput(colors); updateColors(); } } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); Button remove = new Button(comp, SWT.FLAT); remove.setToolTipText("Remove selected colors"); remove.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { IStructuredSelection selection = (IStructuredSelection) tv.getSelection(); colors.removeAll(selection.toList()); tv.setInput(colors); updateColors(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); remove.setImage(Activator.getDefault().getImageRegistry().get(Activator.REMOVE)); Button toggle = new Button(comp, SWT.FLAT); toggle.setToolTipText("Toggle Colors"); toggle.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { nextColors(); tv.setInput(colors); updateColors(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); toggle.setImage(Activator.getDefault().getImageRegistry().get(Activator.TOGGLE_COLORS)); comp = new Composite(buttons, SWT.NONE); gd = new GridData(SWT.FILL, SWT.FILL, true, false); gd.horizontalSpan=2; comp.setLayout(new GridLayout(2, true)); comp.setLayoutData(gd); final Button bg = new Button(comp, SWT.FLAT); bg.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); bg.setText("Background"); bg.setImage(createImageFromColor(viewer.getCloud().getBackground().getRGB(), 16)); bg.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { ColorDialog cd = new ColorDialog(parent.getShell()); RGB color = cd.open(); if(color == null) return; Color old = viewer.getCloud().getBackground(); Color c = new Color(Display.getDefault(), color); viewer.getCloud().setBackground(c); old.dispose(); viewer.getCloud().redrawTextLayerImage(); Image oldImage = bg.getImage(); Image newImage = createImageFromColor(color, 16); bg.setImage(newImage); oldImage.dispose(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); final Button sel = new Button(comp, SWT.FLAT); sel.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false)); sel.setText("Selection"); sel.setImage(createImageFromColor(viewer.getCloud().getSelectionColor().getRGB(), 16)); sel.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { ColorDialog cd = new ColorDialog(parent.getShell()); RGB color = cd.open(); if(color == null) return; Color old = viewer.getCloud().getSelectionColor(); Color c = new Color(Display.getDefault(), color); viewer.getCloud().setSelectionColor(c); old.dispose(); viewer.getCloud().redrawTextLayerImage(); Image oldImage = sel.getImage(); Image newImage = createImageFromColor(color, 16); sel.setImage(newImage); oldImage.dispose(); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); return buttons; } protected Group addLayoutButtons(Composite parent) { Group buttons = new Group(parent, SWT.SHADOW_IN); buttons.setLayout(new GridLayout(2, true)); buttons.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); Label l = new Label(buttons, SWT.NONE); l.setText("Number of Words"); final Combo words = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY); words.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); words.setItems(new String[] {"100","200","300","400","500","600","700","800","900","1000", "1100", "1200", "1300", "1400", "1500","1600", "1700", "1800", "1900", "2000"}); words.select(2); words.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { String item = words.getItem(words.getSelectionIndex()); viewer.setMaxWords(Integer.parseInt(item)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); l = new Label(buttons, SWT.NONE); l.setText("Max Font Size"); final Combo font = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY); font.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); font.setItems(new String[] {"50", "100", "150", "200", "250", "300", "350", "400", "450", "500"}); font.select(1); font.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { String item = font.getItem(font.getSelectionIndex()); viewer.getCloud().setMaxFontSize(Integer.parseInt(item)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); l = new Label(buttons, SWT.NONE); l.setText("Min Font Size"); final Combo minFont = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY); minFont.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); minFont.setItems(new String[] {"10", "15", "20", "25", "30", "35", "40", "45", "50"}); minFont.select(1); minFont.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { String item = minFont.getItem(minFont.getSelectionIndex()); viewer.getCloud().setMinFontSize(Integer.parseInt(item)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); l = new Label(buttons, SWT.NONE); l.setText("Boost"); final Combo boost = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY); boost.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); boost.setItems(new String[] {"0", "1", "2","3","4","5","6","7","8","9","10"}); boost.select(0); boost.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { String item = boost.getItem(boost.getSelectionIndex()); viewer.setBoost(Integer.parseInt(item)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); l = new Label(buttons, SWT.NONE); l.setText("Boost Factor"); final Combo boostFactor = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY); boostFactor.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); boostFactor.setItems(new String[] {"1","1.5","2","2.5","3","3.5", "4", "4.5", "5"}); boostFactor.select(0); boostFactor.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { String item = boostFactor.getItem(boostFactor.getSelectionIndex()); viewer.setBoostFactor(Float.parseFloat(item)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); if(viewer.getLabelProvider() instanceof IEditableCloudLabelProvider) { } l = new Label(buttons, SWT.NONE); l.setText("Angles"); final Combo angles = new Combo(buttons, SWT.DROP_DOWN | SWT.READ_ONLY); angles.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); angles.setItems(new String[] {"Horizontal only", "Vertical only", "Horizontal & Vertical", "45 Degrees, mostly horizontal", "45 Degrees", "Random"}); final List<List<Float>> anglesLists = new ArrayList<List<Float>>(); anglesLists.add(Arrays.asList(0F)); anglesLists.add(Arrays.asList(-90F,90F)); anglesLists.add(Arrays.asList(0F,-90F,0F,90F)); anglesLists.add(Arrays.asList(0F,-90F,-45F, 0F,45F, 90F,0F,0F,0F,0F)); anglesLists.add(Arrays.asList(-90F,-45F, 0F,45F, 90F)); List<Float> tmp = new ArrayList<Float>(); for(int i = -90; i <= 90; i++) { tmp.add((float) i); } anglesLists.add(tmp); angles.select(0); angles.addSelectionListener(new SelectionListener() { @Override public void widgetSelected(SelectionEvent e) { int index = angles.getSelectionIndex(); IEditableCloudLabelProvider lp = (IEditableCloudLabelProvider) viewer.getLabelProvider(); lp.setAngles(anglesLists.get(index)); } @Override public void widgetDefaultSelected(SelectionEvent e) {} }); return buttons; } public List<RGB> getColors() { return colors; } public List<FontData> getFonts() { return fonts; } }